package ia1011.zanzibar.chaos.parser;

import ia1011.zanzibar.chaos.type.UimaComplexConstituent;
import ia1011.zanzibar.chaos.type.UimaConstituent;
import ia1011.zanzibar.chaos.type.UimaLemma;
import ia1011.zanzibar.chaos.type.UimaParagraph;
import ia1011.zanzibar.chaos.type.UimaSentence;
import ia1011.zanzibar.chaos.type.UimaSimpleConstituent;
import ia1011.zanzibar.chaos.type.UimaToken;

import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.cas.FSArray;
import org.apache.uima.jcas.cas.StringArray;

import chaos.ConfigurationHandler;
import chaos.XDG.Constituent;
import chaos.XDG.ConstituentList;
import chaos.XDG.Lemma;
import chaos.XDG.SimpleConst;
import chaos.XDG.Token;
import chaos.XDG.XDG;
import chaos.alternatives.AvailableLanguage;
import chaos.alternatives.AvailableProcessor;
import chaos.processors.Parser;
import chaos.processors.ProcessorException;
import chaos.textstructure.Paragraph;
import chaos.textstructure.Text;
import chaos.XDG.ComplxConst;

public class ChaosParser {	
	
	private Vector<AvailableProcessor> modules;
	private AvailableLanguage language;
	private Parser parser;
	private Text text;	
	
	public ChaosParser(AvailableLanguage language) throws ProcessorException {
		super();
		this.language = language;
		ConfigurationHandler.initialize();
		ConfigurationHandler.parseKBPropFile(language.name(), System.getProperty("chaos.default.kb"));
		parser = new Parser();
		parser.initialize();
	}
	
	public ChaosParser(Vector<AvailableProcessor> modules, AvailableLanguage language) throws ProcessorException {
		super();
		this.modules = modules;
		this.language = language;
		ConfigurationHandler.initialize();
		ConfigurationHandler.parseKBPropFile(language.name(), System.getProperty("chaos.default.kb"));
		parser = new Parser();
		parser.initialize();
	}

	public Vector<AvailableProcessor> getModules() {
		return modules;
	}
	
	public void setModules(Vector<AvailableProcessor> modules) {
		this.modules = modules;
	}

	public AvailableLanguage getLanguage() {
		return language;
	}
	
	public void setLanguage(AvailableLanguage language) {
		this.language = language;
	}

	public Text getText() {
		return text;
	}

	public void setText(Text text) {
		this.text = text;
	}
	
	public void setText(String text) {
		this.text = new Text(text);
	}	

	private String convertModulesList(){
		String moduleList = "";
		for(int i=0;i<modules.size();i++){
			if(i==modules.size()-1){
				moduleList+=modules.get(i).name();
			} else {
				moduleList+=modules.get(i).name()+",";
			}			
		}
		return moduleList;
	}	
	
	public void parseNoChunker(JCas jcas) throws ProcessorException{		
		text = new Text(jcas.getDocumentText());
		text = parser.run(text, modules);
		Vector<Paragraph> paragrafi = text.getParagraphs();		
		for(int i=0; i< paragrafi.size(); ++i){
			UimaParagraph UimaParagraph = new UimaParagraph(jcas);			
			Paragraph paragrafo = paragrafi.get(i);
			UimaParagraph= new UimaParagraph(jcas);
			UimaParagraph.setBegin(paragrafo.getStart());
			UimaParagraph.setEnd(paragrafo.getEnd());
			UimaParagraph.setId(paragrafo.getId());
			UimaParagraph.setCaseSensitive(paragrafo.getCaseSensitive());			
			Vector<XDG> frasi = paragrafo.getXdgs();
			FSArray frasiList = new FSArray(jcas, paragrafi.size());
			for(int j=0;j<frasi.size();j++){
				XDG frase = frasi.get(j);
				UimaSentence UimaFrase = new UimaSentence(jcas);
				int sentenceStart = getSentenceStart(frase);
				int sentenceEnd = getSentenceEnd(frase);
				UimaFrase.setBegin(sentenceStart);
				UimaFrase.setEnd(sentenceEnd);
				UimaFrase.setCaseSensitive(frase.getCaseSensitive());
				ConstituentList constList = frase.getSetOfConstituents();
				FSArray constituentiList = new FSArray(jcas, constList.size());
				for(int k=0;k<constList.size();k++){
					SimpleConst simple = (SimpleConst)constList.getElementAt(k);					
					UimaSimpleConstituent UimaSimple = new UimaSimpleConstituent(jcas);
					//imposto i dati di costiuent
					UimaSimple.setBegin(simple.getTokenStartOffset());
					UimaSimple.setEnd(simple.getTokenEndOffset());
					UimaSimple.setId(simple.getId());
					UimaSimple.setKind(simple.getType());
					UimaSimple.setCoindex(simple.getCoindex());
					UimaSimple.setMorphologicalFeatures(simple.getMorphologicalFeatures());
					Vector<Token> tokens = simple.getTokenSpan();
					FSArray tokenList = new FSArray(jcas, tokens.size());
					for(int s=0;s<tokens.size();s++){
						Token tok = tokens.get(s);
						UimaToken UimaToken = new UimaToken(jcas);
						UimaToken.setBegin(tok.getStart());
						UimaToken.setEnd(tok.getEnd());
						UimaToken.setSurface(tok.getSurface());
						UimaToken.setId(tok.getId());
						UimaToken.setPositionInParagraph(tok.getPositionInParagraph());
						tokenList.set(s, UimaToken);
						UimaToken.addToIndexes();
						Vector<Lemma> lemmas = (Vector<Lemma>)simple.getAlternativeLemmas();
						FSArray lemmalist = new FSArray(jcas, lemmas.size());
						for(int v = 0;v<lemmas.size();v++){
							UimaLemma UimaLemma = new UimaLemma(jcas);
							UimaLemma.setBegin(tokens.get(s).getStart());
							UimaLemma.setEnd(tokens.get(s).getEnd());
							UimaLemma.setKind(lemmas.get(v).getType());
							UimaLemma.setSurface(lemmas.get(v).getSurface());
							UimaLemma.setId(lemmas.get(v).getId());
							UimaLemma.setMorphologicalFeatures(lemmas.get(v).getMorphologicalFeatures());
							Vector<String> wordsense = lemmas.get(v).getAlternativeWordSenses();
							StringArray wordsenseList = new StringArray(jcas, wordsense.size());
							for(int z = 0; z < wordsense.size(); z++){
								wordsenseList.set(z, wordsense.get(z));						
							}						
							UimaLemma.setWordsenses(wordsenseList);
							UimaLemma.addToIndexes();
							lemmalist.set(v, UimaLemma);
							UimaSimple.setAlternativeLemmas(lemmalist);
						}
					}										
					
					UimaSimple.setTokens(tokenList);					
					UimaSimple.addToIndexes();					
					constituentiList.set(k, UimaSimple);
				}
				frasiList.set(j, UimaFrase);
				UimaFrase.setConstituents(constituentiList);
				UimaFrase.addToIndexes();								
			}
			UimaParagraph.setSentences(frasiList);
			UimaParagraph.addToIndexes();
		}
		parser.finalize();
	}
	
	public int getSentenceStart(XDG x){		
		ConstituentList list = x.getSetOfConstituents();
		Constituent c = list.getElementAt(0);
		return c.getTokenStartOffset();
	}
	
	public int getSentenceEnd(XDG x){		
		ConstituentList list = x.getSetOfConstituents();
		Constituent c = list.getElementAt(list.size()-1);
		return c.getTokenEndOffset();
	}
	
	
	
	private int getStart(Constituent constituent) {
		if (constituent instanceof SimpleConst) {
			SimpleConst simple = (SimpleConst) constituent;
			return simple.getTokenStartOffset();
		} else {
			ComplxConst complex = (ComplxConst) constituent;
			Constituent c = (Constituent) complex.getSubConstituents().get(0);
			return getStart(c);
		}
	}

	private int getEnd(Constituent constituent) {
		if (constituent instanceof SimpleConst) {
			SimpleConst simple = (SimpleConst) constituent;
			return simple.getTokenEndOffset();
		} else {
			ComplxConst complex = (ComplxConst) constituent;
			Constituent c = (Constituent) complex.getSubConstituents().get(
					complex.getSubConstituents().size() - 1);
			return getStart(c);
		}
	}	
}
